package com.example.myweb.Service.Auth.Impl;

import com.example.myweb.Domain.Entity.Draft;
import com.example.myweb.Domain.Entity.User;
import com.example.myweb.Dto.DraftSaveRequestDTO;
import com.example.myweb.Dto.DraftSummaryDTO;
import com.example.myweb.Exception.CustomException;
import com.example.myweb.Repository.JpaRepository.DraftRepository;
import com.example.myweb.Service.Auth.DraftService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DraftServiceImpl implements DraftService {

    @Autowired
    private DraftRepository draftRepository;
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    @Transactional
    public DraftSummaryDTO saveDraft(DraftSaveRequestDTO request, User currentUser) {
        Draft.DraftType typeEnum;
        try {
            typeEnum = Draft.DraftType.valueOf(request.getType().toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new CustomException("无效的草稿类型: " + request.getType(), HttpStatus.BAD_REQUEST);
        }

        // 我们简化逻辑：一个用户同种类型的草稿只保留一份最新的。
        // 先查找，如果存在就更新，不存在就新建。
        List<Draft> existingDrafts = draftRepository.findByUserAndType(currentUser, typeEnum);
        Draft draft = existingDrafts.stream().findFirst().orElse(new Draft());

        draft.setUser(currentUser);
        draft.setType(typeEnum);

        try {
            String contentJson = objectMapper.writeValueAsString(request.getContent());
            draft.setContent(contentJson);
        } catch (JsonProcessingException e) {
            throw new CustomException("草稿内容格式错误，无法序列化", HttpStatus.INTERNAL_SERVER_ERROR);
        }

        Draft savedDraft = draftRepository.save(draft);
        return convertToSummaryDto(savedDraft);
    }

    @Override
    @Transactional(readOnly = true)
    public List<DraftSummaryDTO> getUserDrafts(User currentUser) {
        return draftRepository.findByUserOrderByLastSavedTimeDesc(currentUser)
                .stream()
                .map(this::convertToSummaryDto)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void deleteDraft(Long draftId, User currentUser) {
        Draft draft = draftRepository.findById(draftId)
                .orElseThrow(() -> new CustomException("草稿不存在", HttpStatus.NOT_FOUND));

        if (!draft.getUser().getUserId().equals(currentUser.getUserId())) {
            throw new CustomException("无权删除他人草稿", HttpStatus.FORBIDDEN);
        }
        draftRepository.delete(draft);
    }

    @Override
    @Transactional(readOnly = true)
    public Object getDraftContent(Long draftId, User currentUser) {
        Draft draft = draftRepository.findById(draftId)
                .orElseThrow(() -> new CustomException("草稿不存在", HttpStatus.NOT_FOUND));

        if (!draft.getUser().getUserId().equals(currentUser.getUserId())) {
            throw new CustomException("无权查看他人草稿", HttpStatus.FORBIDDEN);
        }

        try {
            // 将JSON字符串反序列化回原始的对象结构
            return objectMapper.readValue(draft.getContent(), Object.class);
        } catch (IOException e) {
            throw new CustomException("草稿内容损坏，无法解析", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private DraftSummaryDTO convertToSummaryDto(Draft draft) {
        DraftSummaryDTO dto = new DraftSummaryDTO();
        dto.setDraftId(draft.getDraftId());
        dto.setType(draft.getType().name().toLowerCase());
        dto.setLastSavedTime(draft.getLastSavedTime());

        try {
            Map<String, Object> contentMap = objectMapper.readValue(draft.getContent(), Map.class);
            dto.setTitle((String) contentMap.getOrDefault("title", "无标题"));
            String contentText = (String) contentMap.getOrDefault("content", "");
            dto.setSummary(contentText.substring(0, Math.min(contentText.length(), 50)) + "...");
        } catch (Exception e) {
            dto.setTitle("草稿内容解析失败");
            dto.setSummary("...");
        }

        return dto;
    }
}
